import staticMethods from "antd/es/message";
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios";

import store from "@/store";

import { canceler } from "./utils/AxiosCanceler.ts";

class Request {
	public service: AxiosInstance;

	public constructor(config: AxiosRequestConfig) {
		// 实例化axios
		this.service = axios.create(config);
		this.service.interceptors.request.use(
			request => {
				canceler.addPending(request);
				const token = store.getState().public.token;
				if (request.headers && token) {
					request.headers["x-access-token"] = token;
				}
				return request;
			},
			(error: AxiosError) => {
				return Promise.reject(error);
			}
		);

		this.service.interceptors.response.use(
			async (response: AxiosResponse) => {
				const { data, config } = response;
				canceler.removePending(config);
				// 全局错误请求拦截
				if (data["status_code"] !== 200) {
					staticMethods.error("网络请求异常，请稍后在试");
					return Promise.reject(data);
				}
				return Promise.resolve(data);
			},
			async (error: AxiosError) => {
				const { response, message: msg } = error;
				if (msg.indexOf("timeout") !== -1) {
					staticMethods.error("请求超时，请稍后再试");
				}
				if (response) {
					const message = this.checkStatus(response.status);
					staticMethods.error(message);
				}
				// 服务器结果都没有返回(可能服务器错误可能客户端断网) 断网处理:可以跳转到断网页面
				if (!window.navigator.onLine) {
					window.location.replace("/login");
				}
				return Promise.reject(error);
			}
		);
	}

	public request = <T>(config: AxiosRequestConfig): Promise<T> => {
		return this.service.request(config);
	};

	private checkStatus = (status: number): string => {
		switch (status) {
			case 400:
				return "请求失败！请您稍后重试";
			case 401:
				return "登录失效！请您重新登录";
			case 403:
				return "当前账号无权限访问！";
			case 404:
				return "你所访问的资源不存在！";
			case 405:
				return "请求方式错误！请您稍后重试";
			case 408:
				return "请求超时！请您稍后重试";
			case 500:
				return "服务异常！";
			case 502:
				return "网关错误！";
			case 503:
				return "服务不可用！";
			case 504:
				return "网关超时！";
			default:
				return "请求失败！";
		}
	};
}

export const { request } = new Request({
	baseURL: "/",
	timeout: 10000
});
